package yxy.cherry.paycenter.servlet.channel.huawei_quick;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import jodd.util.StringUtil;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.util.TextUtils;
import yxy.apple.logger.Logger;
import yxy.apple.util.Base64Utility;
import yxy.apple.util.MathUtil;
import yxy.apple.util.SdkUtil;
import yxy.apple.util.StringUtillity;
import yxy.cherry.data.DataCenter;
import yxy.cherry.data.bean.charge;
import yxy.cherry.game.base.bean.SDKParm;
import yxy.cherry.game.base.bean.SdkParmEnum;
import yxy.cherry.paycenter.channelmodule.ActType;
import yxy.cherry.paycenter.channelmodule.sdk_huawei_quick.PayMoudle_huawei_quick;
import yxy.cherry.paycenter.channelmodule.sdk_jh.PayMoudle_jh;
import yxy.cherry.paycenter.database.dao.orderinfoDao;
import yxy.cherry.paycenter.database.dao.ordersDao;
import yxy.cherry.paycenter.database.db.orderinfo;
import yxy.cherry.paycenter.database.db.orders;
import yxy.cherry.paycenter.servlet.channel.Servlet;
import yxy.cherry.paycenter.util.HttpUtil;
import yxy.game.pm2.bean.Currency;
import yxy.game.pm2.bean.channel.SdkChannel;
import yxy.game.pm2.bean.db.sdk.SDK_UnionChannel;
import yxy.game.pm2.bean.db.sdk.SDK_UnionChannelDAO;
import yxy.game.pm2.bean.module.OrderInfoModule;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;

//华为快游戏，支付结果通知
public class Servlet_huawei_quick extends Servlet{
	public static final String SIGN_ALGORITHMS = "SHA1WithRSA";
	public static final String SIGN_ALGORITHMS256 = "SHA256WithRSA";
	public static final String SIGN_MD5WITHRSA = "MD5WithRSA";

	private static final Logger logger = Logger.create(Servlet_huawei_quick.class);

	@Override
	public String getChannel() {
		return SdkChannel.sdk_huawei_quick;
	}

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		super.doGet(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//参考文档：
		// https://developer.huawei.com/consumer/cn/doc/development/HMS-2-References/hmssdk_jointOper_api_reference_s1
		JSONObject rjson = new JSONObject();
		try {
			JSONObject json = HttpUtil.getParseJSON(req);
			logger.info(SdkChannel.sdk_huawei_quick + ":" + json.toJSONString());

			String result = json.getString("result");
			String userName = json.getString("userName"); //商户ID，即华为开发者联盟给开发者分配的“支付ID”
			String productName = json.getString("productName");
			String payType = json.getString("payType");
			String amount = json.getString("amount"); //元，商品支付金额，金额会保留2位小数，例如：20.00。
			String currency = json.getString("currency"); //如果支付时未传该参数或参数值为CNY
			String orderId = json.getString("orderId"); //华为支付平台订单号。
			String notifyTime = json.getString("notifyTime"); //时间戳，即自1970年1月1日0时起的毫秒数。
			String requestId = json.getString("requestId"); //由开发者应用在支付时自行生成的订单号
			String bankId = json.getString("bankId");
			String orderTime = json.getString("orderTime"); //下单时间，格式为yyyy-MM-dd hh:mm:ss。
			String tradeTime = json.getString("tradeTime"); //完成交易时间，格式为yyyy-MM-dd   hh:mm:ss
			String accessMode = json.getString("accessMode");
			String spending = json.getString("spending");
			String extReserved = json.getString("extReserved"); //透传参数，用户code
			String sysReserved = json.getString("sysReserved");
			String timeOffset = json.getString("timeOffset");
			String signType = json.getString("signType"); //取值默认为RSA256
			String sign = json.getString("sign");

			if (StringUtil.isAllEmpty(userName, amount, orderId, requestId, sign))
				throw new Exception("参数异常");

			//myorderid 为空
			if(requestId != null && !requestId.equals("")) {
				orderinfo oinfo = new orderinfo();
				oinfo.setMyorderid(requestId);
				oinfo.setOtherinfo(json.toString());
				orderinfoDao.add(oinfo);
			}


			//订单状态 0 支付成功，不成功的订单不处理
			if (!"0".equals(result)) throw new Exception("result status error");
			//渠道参数核对
			SDK_UnionChannel unionChannel = SDK_UnionChannelDAO.getByAppKey(SdkChannel.sdk_huawei_quick, userName);
			if (unionChannel == null) throw new Exception("渠道异常");
			//订单核对，是否存在
			orders o = ordersDao.getOrderByMyorderid(requestId);
			logger.info("order %s", JSON.toJSONString(o));
			if (o == null) throw new Exception("order null");
			//已经是成功的订单，不用重复处理
			if (o.getOrderstate() == 1) {
				rjson.put("result", 0);
				returnInfo(rjson, resp);
				return;
			}
			//订单用户核对
			//if ( extReserved.equals(order.getPlayercode()) ) throw new Exception("user error");
			//金额核对
			int fee = Integer.parseInt(MathUtil.str_multiply(amount, "100", 0)); //转成分
			if (fee != o.getGoodsprice()) throw new Exception("amount error");

			//sign校验
			Map<String, String> params = json.toJavaObject(Map.class);
			params.remove("sign");
			params.remove("signType");
			String signContent = SdkUtil.mapToContent(params, true);
			logger.info("params : %s ", JSON.toJSON(params));
			logger.info("signContent : %s ", signContent);
			String publicKey = unionChannel.getPublicKey();
			if ( !doCheck(signContent, sign, publicKey, "RSA256") ) throw new Exception("sign error");


			o.setPlatorderid(orderId);
			o.setUpdatetime(new Date());
			o.setPayamount(fee);
			o.setOrderstate(OrderInfoModule.orderinfofinish);
			ordersDao.update(o);

			ActType at = ActType.getat(o.getActtype());
//		PayType pt = PayType.getpt(at.getPaytype());
			PayMoudle_huawei_quick am = new PayMoudle_huawei_quick();
			ArrayList<Currency> curs = am.getRewardInfoByType(o.getPlayercode(), at, o.getGoodsid());

			charge charge = DataCenter.getData(o.getGoodsid(), charge.class);
			am.createOrderInfoModule(o, curs, charge.getVipexp(), o.getGoodsprice());

			rjson.put("result", 0);
		} catch (Exception e) {
			e.printStackTrace();
			rjson.put("result", 99);
		}

		returnInfo(rjson, resp);
		return;
	}

	/**
	 * 校验签名信息
	 * @param  content 待校验字符串
	 * @param sign  签名字符串
	 * @param publicKey 公钥
	 * @param signType 加密类型
	 * @param 是否校验通过
	 */
	public static boolean doCheck(String content, String sign, String publicKey, String signtype) {
		try {
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			byte[] encodedKey = Base64.decodeBase64(publicKey);
			PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
			java.security.Signature signature = null;
			if ("RSA256".equals(signtype)) {
				signature = java.security.Signature.getInstance(SIGN_ALGORITHMS256);
			} else {
				signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
			}
			signature.initVerify(pubKey);
			signature.update(content.getBytes("utf-8"));
			boolean bverify = signature.verify(Base64.decodeBase64(sign));
			return bverify;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}
}
